package com.xinjian.jianba.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.qiniu.cdn.CdnManager;
import com.qiniu.cdn.CdnResult;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.BatchStatus;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.Json;
import com.qiniu.util.StringMap;
import com.xinjian.jianba.dto.QiuNiuErrorVo;
import com.xinjian.jianba.dto.QiuNiuJhDto;
import com.xinjian.jianba.exception.BusinessException;
import com.xinjian.jianba.exception.ResponseCode;
@Component
public class QiNiuUtil {
	 //设置好账号的ACCESS_KEY和SECRET_KEY
    public static  String ACCESS_KEY;
    public static  String SECRET_KEY;
  	public static  String bucketname;
  	public static  String domainOfBucket;
  	public static  String protocol;
  	private static String BACKURL;//正式"https://jianjianla.com"; //测试 http://www.jijile.vip
  	public static String backRequestUri="/api/v3/jianba/qiniuyun/callBack";
  	@Value("${jianba.qiniu.protocol}")
  	public void setProtocol(String protocol) {
		QiNiuUtil.protocol = protocol;
	}
	@Value("${jianba.qiniu.accesskey}")
  	public void setACCESS_KEY(String aCCESS_KEY) {
		ACCESS_KEY = aCCESS_KEY;
	}
  	@Value("${jianba.qiniu.secretkey}")
	public void setSECRET_KEY(String sECRET_KEY) {
		SECRET_KEY = sECRET_KEY;
	}
  	@Value("${jianba.qiniu.bucketname}")
	public void setBucketname(String bucketname) {
		QiNiuUtil.bucketname = bucketname;
	}
  	@Value("${jianba.qiniu.domainOfBucket}")
	public  void setDomainOfBucket(String domainOfBucket) {
		QiNiuUtil.domainOfBucket = domainOfBucket;
	}
  	@Value("${jianba.qiniu.backurl}")
	public  void setBACKURL(String bACKURL) {
		BACKURL = bACKURL;
	}
  	public static String getToken(String key,String userDefined,boolean isOverwrite){
		Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
  		String callBackBody="";
  		String magicVariable="bucket=$(bucket)&hash=$(etag)&key=$(key)&filename=$(fname)";
  		if(userDefined!=null&&!userDefined.equals("")){
  			callBackBody=getCallbackBody(userDefined);
  		}
  		if("".equals(callBackBody)){
  			callBackBody=magicVariable;
  		}else{
  			callBackBody=magicVariable+"&"+callBackBody;
  		}
  		callBackBody=callBackBody+"&action=$(x:action)";
  		StringMap scope=null;
  		if(isOverwrite==true){
  		scope=new StringMap()
                .put("callbackUrl", BACKURL+backRequestUri)//公网访问的回调接口
                .put("callbackBody", callBackBody)
                .put("callbackBodyType", "application/json");
  		}else{
  		scope=new StringMap()
                .put("callbackUrl", BACKURL+backRequestUri)//公网访问的回调接口
                .put("callbackBody", callBackBody)
                .put("insertOnly", 1)
                .put("callbackBodyType", "application/json");
  		}
  		return auth.uploadToken(bucketname, key, 3600,scope);//过期时间3600s
  	}
  	//userDefined不能为null
	public static String getCallbackBody(String userDefined) {
		Pattern p = Pattern.compile("[@#$%^&*]");
        Matcher m = p.matcher(userDefined);
        boolean match = m.find();
        if(match==true){
        	throw new BusinessException(ResponseCode.ERROR, "自定义变量不要包含:@#$%^&*");
        }
		String strDefined=userDefined.replaceAll("\\s*", "");
  		while(strDefined.startsWith("|")){
  			strDefined=strDefined.substring(1);
  		}
  		String[] fieldName=strDefined.split("\\|");
  		StringBuffer callbackBody=new StringBuffer();
  		for(int i=0;i<fieldName.length;i++){
  			if("".equals(fieldName[i])) continue;
  			callbackBody.append(fieldName[i]+"=").append("$(x:").append(fieldName[i]).append(")").append("&");
  		}
  		return callbackBody.length()>0?callbackBody.substring(0,callbackBody.length()-1):"";
	}
	public static String extractObjectToJsonStr(Object result) {
		Map<String,Object> rt=new HashMap<String,Object>();
		rt.put("code", ResponseCode.SUCCESS+"");
		rt.put("message", ResponseCode.SUCCESS_MSG);
		rt.put("result", result);
		String resultStr=  new GsonBuilder().disableHtmlEscaping().create().toJson(rt);
		return resultStr;
	}
	
	public static StringBuffer extractedRequestToStringBuffer(HttpServletRequest request) throws IOException {
		StringBuffer json = new StringBuffer();
		String line = null;
		
			BufferedReader reader = request.getReader();
			while ((line = reader.readLine()) != null) {
			json.append(line);
			}
			if(json.length()<1){
				Map<String, String[]> hm=request.getParameterMap();
				if (hm!=null && hm.size()>0){
				json.append(readjson(hm).toString());
				}
			}
		
		return json;
	}
	
	private static JSONObject readjson(Map<String, String[]> hm){
        JSONObject jobj = new JSONObject();
		//通过循环遍历的方式获得key和value并set到JSONObject中
		Iterator it = hm.keySet().iterator();
		while (it.hasNext()) {
		       String key = it.next().toString();
		       String[] values = (String[])hm.get(key);
		       jobj.put(key, values[0]);
		}
		        return jobj;
		}
	public static String getAddress(String key,String domainOfBucket) throws UnsupportedEncodingException{
		String encodedFileName = URLEncoder.encode(key, "utf-8");
    	String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
    	return finalUrl;
	}
	public static List<QiuNiuErrorVo> delete(String[] keyList){
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(Zone.zone0());
		Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
	    batchOperations.addDeleteOp(bucketname, keyList);
	    String key=null;
	    List<QiuNiuErrorVo> list=new ArrayList<QiuNiuErrorVo>();
	    try{
	    Response response = bucketManager.batch(batchOperations);
	    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
	    for(int i = 0; i < keyList.length; i++) {
	        BatchStatus status = batchStatusList[i];
	         key = keyList[i];
	        QiuNiuErrorVo qiuNiuErrorVo=new QiuNiuErrorVo();
	        if (status.code == 200) {
	        	qiuNiuErrorVo.setCode(200+"");
	        	qiuNiuErrorVo.setKey(key);
	        	qiuNiuErrorVo.setMessage("delete success");
	        	list.add(qiuNiuErrorVo);
	        } else {
	        	qiuNiuErrorVo.setCode(status.code+"");
	        	qiuNiuErrorVo.setKey(key);
	        	qiuNiuErrorVo.setMessage(status.data.error);
	        	list.add(qiuNiuErrorVo);
	        }
	    }
	   }catch(QiniuException ex){
		   QiuNiuErrorVo qiuNiuErrorVo=new QiuNiuErrorVo();
		    qiuNiuErrorVo.setCode(500+"");
        	qiuNiuErrorVo.setKey(key);
       	    qiuNiuErrorVo.setMessage(ex.getMessage());
       	    list.add(qiuNiuErrorVo);
	   }
	    return list;
	}
	
	//三鉴
	public static void sanjian(String image64){
		  Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
		    // 鉴黄API请求地址
	      String requestUrl = "http://argus.atlab.ai/v1/image/censor";
	       // 构造请求body
		  StringMap data = new StringMap();
		  data.put("uri", "data:application/octet-stream;base64,"+image64);
		  StringMap map = new StringMap();
		  map.put("data", data.map());
		  String postBody = Json.encode(map);
		  // 生成accessToken
		  String accessToken = String.format("Qiniu %s", auth.signRequestV2(requestUrl, "POST", postBody.getBytes(), Client.JsonMime));
		  // 构造请求headers
		  StringMap headers = new StringMap();
		  headers.put("Authorization", accessToken);
		  Client client = new Client();
		  StringMap mapRe=null;
		  try {
			com.qiniu.http.Response resp = client.post(requestUrl, postBody.getBytes(), headers, Client.JsonMime);
			mapRe=Json.decode(resp.bodyString());
		  } catch (QiniuException e) {
				throw new BusinessException(ResponseCode.ERROR, e.getMessage());
		  }
		 if(("0.0").equals(mapRe.get("code").toString())||("0").equals(mapRe.get("code").toString())){
			 QiuNiuJhDto qiuNiuJhDto= JsonUtil.json2Obj(mapRe.get("result").toString(), QiuNiuJhDto.class); 
			 List<Map<String,Object>> list=qiuNiuJhDto.getDetails();
			 for(Map<String,Object> Remap:list){
			    	String type=Remap.get("type").toString();
			    	String label=Remap.get("label").toString();
			    	if("politician".equals(type)){
			    		if("1.0".equals(label)){
			    			throw new BusinessException(ResponseCode.ERROR, "图片涉嫌违规");
			    		}
			    	}
			    	if("terror".equals(type)){
			    		if("1.0".equals(label)){
			    			throw new BusinessException(ResponseCode.ERROR, "图片涉嫌违规");
			    		}
			    	}
			    	if("pulp".equals(type)){
			    		if("0.0".equals(label)){
			    			throw new BusinessException(ResponseCode.ERROR, "图片涉嫌违规");
			    		}
			    	}
			    }
		 }
		
	}
	//cdn缓存刷新
//    public static String cdnRefresh(String[] urls){
//    	int code;
//    	String msg=null;
//    	Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
//        CdnManager c = new CdnManager(auth);
//        //待刷新的链接列表
////        String[] urls = new String[]{
////                "http://pb8b069by.bkt.clouddn.com/128/headerLogo"
////                //....
////        };
//        try {
//            //单次方法调用刷新的链接不可以超过100个
//            CdnResult.RefreshResult result = c.refreshUrls(urls);
//        }catch(QiniuException e){
//        	code=e.response.statusCode;
//        	msg=e.response.toString();
//        }
//        return msg;
//    } 
//  	public static void main(String[] args) {
//		String userDefined=" ";
//			String callBackBody="";
//  		String magicVariable="filename=$(fname)&filesize=$(fsize)";
//  		if(userDefined!=null&&!userDefined.equals("")){
//  			callBackBody=getCallbackBody(userDefined);
//  		}
//  		if("".equals(callBackBody)){
//  			callBackBody=magicVariable;
//  		}else{
//  			callBackBody=magicVariable+callBackBody;
//  		}
//  		System.out.println(callBackBody);
//}
	//服务器端覆盖上传
	 public static String upOverWrite(String key,byte[] imgByte) {
		 	//密钥配置
		    Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
	        //<bucket>:<key>，表示只允许用户上传指定key的文件。在这种格式下文件默认允许“修改”，已存在同名资源则会被本次覆盖。
	        //如果希望只能上传指定key的文件，并且不允许修改，那么可以将下面的 insertOnly 属性值设为 1。
	        //第三个参数是token的过期时间
	        String token=auth.uploadToken(bucketname, key);//默认过期时间3600
	        Zone z = Zone.zone0();
	        Configuration c = new Configuration(z);
	        //创建上传对象
	        UploadManager uploadManager = new UploadManager(c);
	        try {
				Response res = uploadManager.put(imgByte, key, token);
				 //解析上传成功的结果
		        DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
		        return protocol+"://"+domainOfBucket+"/"+putRet.key;
			} catch (QiniuException e) {
				 Response r = e.response;
		            // 请求失败时打印的异常的信息
		        throw new BusinessException(ResponseCode.ERROR, r.toString());
			} 
	    }
}
